package com.bbva.kyfb.kyfbbofc.impl;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.bbva.jee.arq.spring.core.gce.ExcepcionEjecucionAplicacion;
import com.bbva.kyfb.kyfbbofc.IFicherosBo;
import com.bbva.kyfb.kyfbdaofc.IFicherosDao;
import com.bbva.kyfb.kyfbdto.firmas.bo.Auditoria;
import com.bbva.kyfb.kyfbdto.firmas.bo.FicheroConfeccion;
import com.bbva.kyfb.kyfbdto.firmas.bo.FicheroInfo;
import com.bbva.kyfb.kyfbdto.firmas.bo.UsuarioInfo;
import com.bbva.kyfb.kyfbdto.firmas.errores.Errores_kyfb_servicios;
import com.bbva.kyfb.kyfbdto.firmas.filtros.FiltroFicheros;
import com.bbva.kyfb.kyfbjpatlbh.dominiotlbh.Ttlsbfua;
import com.bbva.kyfb.kyfbjpatlbh.dominiotlbh.TtlsbfuaPK;
import com.bbva.kyfb.kyfbutils.constantes.ConstantesFO;
import com.bbva.kyfb.kyfbutils.constantes.UtilFO;

/**
 * The Class ServicioFicherosBoImpl.
 */
@Component(value = "servicioFicherosBO")
public class ServicioFicherosBoImpl implements IFicherosBo {

	/** The servicio ficheros dao. */
	@Autowired
	private IFicherosDao servicioFicherosDao;

	/** {@inheritDoc}
	 * @see com.bbva.kyfb.kyfbbofc.IFicherosBo#getComponentesConfeccionReferencia(com.bbva.kyfb.kyfbdto.firmas.bo.FicheroInfo)
	 */
	@Override
	public List<FicheroConfeccion> getComponentesConfeccionReferencia(final FicheroInfo file) {
		final FiltroFicheros filtro = createFiltroFromDto(file);
		final List<FicheroConfeccion> resultado = createFicheroConfDtoFromEntity(servicioFicherosDao.findComponentesConfeccionReferencia(file.getCodClienteCash(), filtro, filtro.getCodUsuario() != null));
		//Si no hay resultados se lanza excepcion desde dao
		return resultado;
	}

	/** {@inheritDoc}
	 * @see com.bbva.kyfb.kyfbbofc.IFicherosBo#getComponentesConfeccionReferencia(com.bbva.kyfb.kyfbdto.firmas.bo.FicheroInfo)
	 */
	@Override
	public int getTotalComponentesConfeccionReferencia(final FicheroInfo file) {
		final FiltroFicheros filtro = createFiltroFromDto(file);
		final int resultado = servicioFicherosDao.getTotalComponentesConfeccionReferencia(file.getCodClienteCash(), filtro, filtro.getCodUsuario() != null);
		if (resultado == 0) {
			throw new ExcepcionEjecucionAplicacion(Errores_kyfb_servicios.NO_EXISTEN_DATOS_A_LISTAR);
		}
		return resultado;
	}

	/** {@inheritDoc}
	 * @see com.bbva.kyfb.kyfbbofc.IFicherosBo#deleteComponenteConfeccion(com.bbva.kyfb.kyfbdto.firmas.bo.FicheroInfo, com.bbva.kyfb.kyfbdto.firmas.bo.UsuarioInfo)
	 */
	@Override
	public void deleteComponenteConfeccion(final FicheroInfo file, final UsuarioInfo usuario) {
		try {
			servicioFicherosDao.findComponentesConfeccionReferencia(file.getCodClienteCash(), createFiltroFromDto(file), file.getsUsuarioOrdenante() != null).size();
			servicioFicherosDao.deleteFicheroConfeccion(file.getCodClienteCash(), file.getsTipoOrden()[0], file.getIdOrden(), crearFuaFromDto(file, usuario, UtilFO.BORRADO_INT.shortValue(), UtilFO.BORRADO, "999"));
		} catch (final ExcepcionEjecucionAplicacion e) {
			if(e.getCodigoError().toString().equals(Errores_kyfb_servicios.NO_EXISTEN_DATOS_A_LISTAR.toString())){
				throw new ExcepcionEjecucionAplicacion(Errores_kyfb_servicios.NO_EXISTE_LA_ORDEN_O_SU_ESTADO_NO_PERMITE_ELIMINARLA,e);
			}else{
				throw new ExcepcionEjecucionAplicacion(e.getCodigoError(),e);
			}
		}
	}

	/** {@inheritDoc}
	 * @see com.bbva.kyfb.kyfbbofc.IFicherosBo#getAuditoriaComponenteConfeccion(com.bbva.kyfb.kyfbdto.firmas.bo.FicheroInfo)
	 */
	@Override
	public List<Auditoria> getAuditoriaComponenteConfeccion(final FicheroInfo file) {
		return createAuditoriaDtoFromEntity(servicioFicherosDao.findAuditoriaComponenteConfeccion(file.getCodClienteCash(), file.getsTipoOrden()[0], file.getIdOrden(), file.getsCodEstado()));
	}

	/**
	 * Creates the auditoria dto from entity.
	 *
	 * @param listFua the list fua
	 * @return the list
	 */
	private List<Auditoria> createAuditoriaDtoFromEntity(final List<Ttlsbfua> listFua)
	{
		final ArrayList<Auditoria> listaAuditoria = new ArrayList<Auditoria>();

		final SimpleDateFormat ss = new SimpleDateFormat("yyyyMMdd HHmmssSS");
		try {
			for (final Ttlsbfua fua : listFua) {
				final Auditoria auditoria = new Auditoria();
				//TODO: Peso no disponible
				//auditoria.setdPesoOrden(fua.get);
				//TODO MAPEAR ACCIONES
				auditoria.setsCodAccion(fua.getId().getCodAccion());
				//TODO MAPEAR Estados
				auditoria.setsCodEstado(fua.getCodEstadfic().trim());
				auditoria.setsCodUsuario(fua.getCodUsuario().trim());
				auditoria.setsCodUsuarioFirma(fua.getCodUsufirma().trim());
				auditoria.setsFechaAccion(ss.parse(fua.getFecAccio().trim()+" "+fua.getFecAccion2().trim()));
				auditoria.setsPoderUsuarioFirmante(fua.getCodUsupoder().trim());
				listaAuditoria.add(auditoria);
			}
		} catch (final Exception e) {
			throw new ExcepcionEjecucionAplicacion(Errores_kyfb_servicios.ERROR_FORMATEO_RESPUESTA, e);
		}
		return listaAuditoria;
	}


	/**
	 * Creates the fichero conf dto from entity.
	 *
	 * @param entidades the entidades
	 * @return the list
	 */
	private List<FicheroConfeccion> createFicheroConfDtoFromEntity(final List<Object[]> entidades)
	{
		final ArrayList<FicheroConfeccion> fichConf = new ArrayList<FicheroConfeccion>();
		final SimpleDateFormat ss = new SimpleDateFormat("yyyyMMdd");
		try {
			for (final Object[] o : entidades) {
				int i = 0;
				final FicheroConfeccion fichero = new FicheroConfeccion();
				fichero.setsNombreFichero(((String) o[i]).trim());
				fichero.setdFechaProceso(ss.parse(((String) o[++i]).trim()));
				fichero.setiNumeroOrdenes((Integer) o[++i]);
				fichero.setdImporte((BigDecimal) o[++i]);
				//TODO: mapear a constante para FRONT. Metodo en UTIL
				fichero.setsCodEstadoFichero(((String) o[++i]).trim());
				fichero.setsCodTipoOrden(((String) o[++i]).trim());
				fichero.setsIdOrdenFirmas(((String) o[++i]).trim());
				if (o[i+1] != null) {
					fichero.setsAsunto(((String) o[++i]).trim());
				}
				else{
					i++;
				}
				fichero.setsDivisa(((String) o[++i]).trim());
				fichero.setModoOrden((String) o[++i]);
				fichero.setFormaPago(((String)o[++i]).trim());
				fichConf.add(fichero);
			}
		} catch (final Exception e) {
			throw new ExcepcionEjecucionAplicacion(Errores_kyfb_servicios.ERROR_FORMATEO_RESPUESTA, e);
		}
		return fichConf;
	}

	/**
	 * Creates the filtro from dto.
	 *
	 * @param file the file
	 * @return the filtro ficheros
	 */
	private FiltroFicheros createFiltroFromDto(final FicheroInfo file) {
		FiltroFicheros filtro = null;
		try {
			if (file != null) {
				filtro = new FiltroFicheros();
				if (file.getsCodEstado() != null) {
					//TODO: MAPEAR ESTADOS Y CONSTANTES. METODO ESTATICO EN EL UTILS
					filtro.setEstados(file.getsCodEstado());
				}
				if (file.getsDivisa() != null) {
					filtro.setDivisas(file.getsDivisa());
				}
				if (file.getsFechaDesde() != null) {
					filtro.setFechaProcesoDesde(file.getsFechaDesde());
				}
				if (file.getsFechaHasta() != null) {
					filtro.setFechaProcesoHasta(file.getsFechaHasta());
				}
				if (file.getsImporteDesde() != null) {
					filtro.setImporteDesde(file.getsImporteDesde());
				}
				if (file.getsImporteHasta() != null) {
					filtro.setImporteHasta(file.getsImporteHasta());
				}
				if (file.getsTipoOrden() != null) {
					filtro.setClaseOrden(file.getsTipoOrden());
				}
				if (file.getsUsuarioOrdenante() != null) {
					filtro.setCodUsuario(file.getsUsuarioOrdenante());
				}
				if (file.getIdOrden() != null) {
					filtro.setIdOrden(file.getIdOrden());
				}
				filtro.setOrdenarPor(UtilFO.getCampoOrden(file.getsValorOrdenacion(), ConstantesFO.PET_CONFECCION));
				if (file.getsModoOrdenacion() != null) {
					filtro.setModoOrdenacion(file.getsModoOrdenacion());
				}
				if (file.getsPaginacionDesde() != 0) {
					filtro.setPaginarDesde(file.getsPaginacionDesde());
				}
				if (file.getsPaginacionNumElementos() != 0) {
					filtro.setNumElementos(file.getsPaginacionNumElementos());
				}
			}
		} catch (final Exception e) {
			throw new ExcepcionEjecucionAplicacion(Errores_kyfb_servicios.FORMATO_INCORRECTO, e);
		}
		return filtro;
	}

	/**
	 * Crear fua from dto.
	 *
	 * @param file the file
	 * @param usuario the usuario
	 * @param idAccion the id accion
	 * @param codAccion the cod accion
	 * @param estadoFua the estado fua
	 * @return the ttlsbfua
	 */
	private Ttlsbfua crearFuaFromDto(final FicheroInfo file, final UsuarioInfo usuario, final int idAccion, final short codAccion, final String estadoFua)
	{
		final SimpleDateFormat ss = new SimpleDateFormat("yyyyMMdd");
		final SimpleDateFormat ss2 = new SimpleDateFormat("hhmmssSS");
		final Date dd = new Date();
		final Ttlsbfua auditoria = new Ttlsbfua();
		try {
			auditoria.setAudFmodific(new Date());
			auditoria.setAudUsuario(usuario.getsCodUsuario());
			auditoria.setCodEstadfic(estadoFua);
			auditoria.setCodUsufirma(ConstantesFO.VACIO);
			auditoria.setCodUsupoder(ConstantesFO.VACIO);
			auditoria.setCodUsuario(usuario.getsCodUsuario());
			auditoria.setFecAccio(ss.format(dd));
			auditoria.setFecAccion2(ss2.format(dd).substring(0, ss2.format(dd).length() - 1));
			auditoria.setId(new TtlsbfuaPK(file.getCodClienteCash(), file.getsTipoOrden() [0], file.getIdOrden(), codAccion, idAccion));
		} catch (final Exception e) {
			throw new ExcepcionEjecucionAplicacion(Errores_kyfb_servicios.FORMATO_INCORRECTO, e);
		}
		return auditoria;
	}

	/**
	 * Gets the servicio ficheros dao.
	 *
	 * @return IFicherosDao
	 */
	public IFicherosDao getServicioFicherosDao() {
		return servicioFicherosDao;
	}

	/**
	 * Sets the servicio ficheros dao.
	 *
	 * @param servFicherosDao the new servicio ficheros dao
	 */
	public void setServicioFicherosDao(final IFicherosDao servFicherosDao) {
		this.servicioFicherosDao = servFicherosDao;
	}
}
